using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Data;
using TAAlert.BackTest;
using TALoaders;

namespace TAAlert.Tests
{
    using NUnit.Framework;

    [TestFixture]
    class TestEMAStrategy
    {
        [SetUp]
        public void Init()
        {
            CachedDownloader.clearCache();
        }

        [Test]
        [Category("Calculation")]
        public void EMAStategyGenerate()
        {
            int nEMA = 10;
            DateTime startDate = new DateTime(2010, 5, 1);
            DateTime endDate = new DateTime(2010, 5, 31);

            TestDownloader loader = new TestDownloader();
            SortedList<DateTime, double> prices = loader.getHistoricalPrices("^OMX", new DateTime(2009, 11, 18), new DateTime(2010, 6, 3), QuoteType.AdjClose);

            EMAStrategy emaStrategy = new EMAStrategy(nEMA, startDate, endDate, prices);
            SortedList<DateTime, int> pos = emaStrategy.generate();
            int[] tmp = {1	,-1	,1	,-1	,-1	,1	,1	,-1	,-1	,1	,1	,1	,-1	,-1	,-1	,-1	,-1	,-1	,1	,-1	,-1	,-1	,-1	,-1	,-1	,-1	,-1	,-1	,1	,1	,1};
            List<int> expPos = new List<int>(tmp);
            Assert.AreEqual(expPos, pos.Values, "Position values");
            Assert.AreEqual(startDate, pos.Keys[0], "The first position date");
            Assert.AreEqual(endDate, pos.Keys[pos.Count - 1], "the last position date");

            // test handling of missign dates
            prices.Remove(startDate);
            prices.Remove(endDate);
            emaStrategy = new EMAStrategy(nEMA, startDate, endDate, prices);
            pos = emaStrategy.generate();
            Assert.AreEqual(startDate.AddDays(-1), pos.Keys[0], "If start date missing use the previous date");
            Assert.AreEqual(endDate.AddDays(-1), pos.Keys[pos.Count - 1], "If end date missing use the following date");
        }

        [Test]
        [Category("Calculation")]
        public void TwoEMAStategyGenerate()
        {
            int nEmaShort = 2;
            int nEmaLong = 10;
            DateTime startDate = new DateTime(2010, 5, 1);
            DateTime endDate = new DateTime(2010, 5, 31);
            double volTreashold = double.PositiveInfinity;

            TestDownloader loader = new TestDownloader();
            SortedList<DateTime, double> prices = loader.getHistoricalPrices("^OMX", new DateTime(2009, 11, 18), new DateTime(2010, 6, 3), QuoteType.AdjClose);

            Strategy twoEmaStrategy = new TwoEMAStrategy(nEmaShort, nEmaLong, volTreashold, startDate, endDate, prices);
            SortedList<DateTime, int> pos = twoEmaStrategy.generate();
            int[] tmp = {1 ,1	,1	,1	,-1	,1	,1	,-1	,-1	,1	,1	,1	,-1	,-1	,-1	,-1	,-1	,-1	,-1	,-1	,-1	,-1	,-1	,-1	,-1	,-1	,-1	,-1	,1	,1	,1 };
            List<int> expPos = new List<int>(tmp);
            Assert.AreEqual(expPos, pos.Values, "TwoEMA Position values");
            Assert.AreEqual(startDate, pos.Keys[0], "TwoEMA The first position date");
            Assert.AreEqual(endDate, pos.Keys[pos.Count - 1], "TwoEMA the last position date");

            // Test volatility cut-out
            volTreashold = 0.29;
            twoEmaStrategy = new TwoEMAStrategy(nEmaShort, nEmaLong, volTreashold, startDate, endDate, prices);
            pos = twoEmaStrategy.generate();
            expPos = new List<int>(new int[] { 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, 0, 0, 1, 1 });
            Assert.AreEqual(expPos, pos.Values, "TwoEMA with vol: Position values");

            // test handling of missign dates
            prices.Remove(startDate);
            prices.Remove(endDate);
            volTreashold = double.PositiveInfinity;
            twoEmaStrategy = new TwoEMAStrategy(nEmaShort, nEmaLong, volTreashold, startDate, endDate, prices);
            pos = twoEmaStrategy.generate();
            Assert.AreEqual(startDate.AddDays(-1), pos.Keys[0], "If start date missing use the previous date");
            Assert.AreEqual(endDate.AddDays(-1), pos.Keys[pos.Count - 1], "If end date missing use the following date");
        }

        [Test]
        [Category("Calculation")]
        public void EMAStategyPerfCalculationsOMX()
        {
            int nEMA = 10;
            DateTime startDate = new DateTime(2010, 5, 1);
            DateTime endDate = new DateTime(2010, 5, 31);

            TestDownloader loader = new TestDownloader();
            SortedList<DateTime, double> prices = loader.getHistoricalPrices("^OMX", new DateTime(2009, 11, 18), new DateTime(2010, 6, 3), QuoteType.AdjClose);

            EMAStrategy emaStrategy = new EMAStrategy(nEMA, startDate, endDate, prices);
            SortedList<DateTime, int> pos = emaStrategy.generate();

            PerformanceCalculator perfCalc = new PerformanceCalculator(prices, pos, 0);
            PerfStatistics totStat = perfCalc.calculateStatistics(startDate, endDate);

            double precision = 0.0001;
            Assert.AreEqual(-133.57, totStat.ProfitLoss, precision, "PerformanceCalculator PL calculations");
            Assert.AreEqual(-157.51, totStat.MaxDrawDown, precision, "PerformanceCalculator MaxDrawDown calculations");
            Assert.AreEqual(-133.57 / 157.51, totStat.Calmar, precision, "PerformanceCalculator Calmar Ratio");

            // Test with transaction cost
            double transactionCost = 0.01;
            perfCalc = new PerformanceCalculator(prices, pos, transactionCost);
            totStat = perfCalc.calculateStatistics(startDate, endDate);
            Assert.AreEqual(-133.57 - 206.2696, totStat.ProfitLoss, precision, "Performance Calculator PL with Transaction cost");
            Assert.AreEqual(-344.2086, totStat.MaxDrawDown, precision, "Max DrawDown with Transaction cost");
        }

        [Test]
        [Category("Calculation")]
        public void PerfCalculWithTransactionCost()
        {
            double transactionCost = 0.01; // 1%
            DateTime date = new DateTime(2010, 1, 1);

            int position = 1;
            double price = 100;
            int n = 10;
            DateTime startDate = date;
            DateTime endDate = date.AddDays(n);

            SortedList<DateTime, int> pos = new SortedList<DateTime, int>(n);
            SortedList<DateTime, double> prices = new SortedList<DateTime, double>(n);
            for (int i = 0; i < n; ++i)
            {
                pos.Add(date, position);
                prices.Add(date, price);

                date = date.AddDays(1);
                position = position * -1;
            }


            PerformanceCalculator perfCalc0 = new PerformanceCalculator(prices, pos, 0);
            PerformanceCalculator perfCalcTC = new PerformanceCalculator(prices, pos, transactionCost);

            PerfStatistics totStat0 = perfCalc0.calculateStatistics(startDate, endDate);
            PerfStatistics totStatTC = perfCalcTC.calculateStatistics(startDate, endDate);
            Assert.AreEqual(totStat0.ProfitLoss - (pos.Count - 1) * price * transactionCost * 2, totStatTC.ProfitLoss, "Compare P/L with and without transaction cost");
        }

        [Test]
        [Category("Calculation")]
        public void EMAStategyPerfCalculationsRussel3000()
        {
            // Set up EMA 
            int nEMA = 27;
            DateTime startDate = new DateTime(2010, 1, 1);  // this date is missing in the input data
            DateTime endDate = new DateTime(2010, 6, 26);   // this date is missing in the input data
            SortedList<DateTime, double> prices = getRussel3000Prices();
            EMAStrategy emaStrategy = new EMAStrategy(nEMA, startDate, endDate, prices);
            SortedList<DateTime, int> pos = emaStrategy.generate();
            int[] tmp = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1 };
            List<int> expPos = new List<int>(tmp);
            Assert.AreEqual(expPos, pos.Values, "Position values");
            Assert.AreEqual(new DateTime(2009, 12, 31), pos.Keys[0], "Correctly recalculated startDate");
            Assert.AreEqual(new DateTime(2010, 6, 25), pos.Keys[pos.Count - 1], "Correctly recalculated endDate");

            PerformanceCalculator perfCalc = new PerformanceCalculator(prices, pos, 0);
            PerfStatistics totStat = perfCalc.calculateStatistics(startDate, endDate);
            double precision = 0.0001;
            Assert.AreEqual(83.12, totStat.ProfitLoss, precision, "PerformanceCalculator PL calculations");
            Assert.AreEqual(-54.32, totStat.MaxDrawDown, precision, "PerformanceCalculator MaxDrawDown calculations");
            Assert.AreEqual(83.12 / 54.32, totStat.Calmar, precision, "PerformanceCalculator Calmar Ratio");
        }

        [Test]
        [Category("Calculation")]
        public void IntraPerfMonthlyCalculationsRussel3000()
        {
            // Set up EMA 
            int nEMA = 27;
            DateTime startDate = new DateTime(2010, 1, 1);  // missing in the input data
            DateTime endDate = new DateTime(2010, 6, 26);   // missing in the input data
            SortedList<DateTime, double> prices = getRussel3000Prices();
            EMAStrategy emaStrategy = new EMAStrategy(nEMA, startDate, endDate, prices);
            SortedList<DateTime, int> pos = emaStrategy.generate();

            // Do Performance Calculations Monthly
            PerformanceCalculator perfCalc = new PerformanceCalculator(prices, pos, 0);
            List<PerfStatistics> stat = perfCalc.calcIntraPeriodStatistics(startDate, endDate, PerformanceCalculator.Frequency.Monthly);

            double precision = 0.00001;
            Assert.AreEqual(new DateTime(2010, 1, 29), stat[0].EndDate, "End of January");
            Assert.AreEqual(27.70, stat[0].ProfitLoss, precision, "January PL");
            Assert.AreEqual(-19.28, stat[0].MaxDrawDown, precision, "January Max DrawDown");
            Assert.AreEqual(1.436721992, stat[0].Calmar, precision, "January Calmar Ratio");

            Assert.AreEqual(new DateTime(2010, 2, 26), stat[1].EndDate, "End of February");
            Assert.AreEqual(-20.83, stat[1].ProfitLoss, precision, "February PL");
            Assert.AreEqual(-31.87, stat[1].MaxDrawDown, precision, "February Max DrawDown");
            Assert.AreEqual(-0.65359272, stat[1].Calmar, precision, "February Calmar Ratio");

            Assert.AreEqual(new DateTime(2010, 3, 31), stat[2].EndDate, "End of March");

            int ixJune = stat.Count - 1;
            Assert.AreEqual(new DateTime(2010, 6, 25), stat[ixJune].EndDate, "End of June - the last date");
            Assert.AreEqual(-18.57, stat[ixJune].ProfitLoss, precision, "June PL");
            Assert.AreEqual(-54.32, stat[ixJune].MaxDrawDown, precision, "June Max DrawDown");
            Assert.AreEqual(-0.341863034, stat[ixJune].Calmar, precision, "June Calmar Ratio");

            // Compare sum of monthly PLs with total PL
            double totPL = 0;
            foreach (PerfStatistics s in stat)
                totPL += s.ProfitLoss;
            PerfStatistics totStat = perfCalc.calculateStatistics(startDate, endDate);
            Assert.AreEqual(totStat.ProfitLoss, totPL, precision, "Total PL should be sum of monthly PLs");
        }

        [Test]
        [Category("Calculation")]
        public void IntraPerfYearlyCalculationsRussel3000()
        {
            // Set up EMA 
            int nEMA = 27;
            DateTime startDate = new DateTime(2009, 1, 1);  // missing in the input data
            DateTime endDate = new DateTime(2010, 6, 26);   // missing in the input data
            SortedList<DateTime, double> prices = getRussel3000Prices();
            EMAStrategy emaStrategy = new EMAStrategy(nEMA, startDate, endDate, prices);
            SortedList<DateTime, int> pos = emaStrategy.generate();

            // Do Performance Calculations Yearly
            double transCost = 0;
            PerformanceCalculator perfCalc = new PerformanceCalculator(prices, pos, transCost);
            List<PerfStatistics> stat = perfCalc.calcIntraPeriodStatistics(startDate, endDate, PerformanceCalculator.Frequency.Yearly);
            Assert.AreEqual(2, stat.Count, "Size of statistics");

            PerfStatistics stat2010 = stat[stat.Count-1];
            double precision = 0.0001;
            Assert.AreEqual(83.12, stat2010.ProfitLoss, precision, "PerformanceCalculator Yearly PL calculations");
            Assert.AreEqual(-54.32, stat2010.MaxDrawDown, precision, "PerformanceCalculator Yearly MaxDrawDown calculations");
            Assert.AreEqual(83.12 / 54.32, stat2010.Calmar, precision, "PerformanceCalculator Yearly Calmar Ratio");
        }

        [Test]
        [Category("Calculation")]
        public void BackTestManagerEMAStrategy()
        {
            DateTime startDate = new DateTime(2009, 11, 30);
            DateTime endDate = new DateTime(2010, 5, 31);
            int nMIN = 2;
            int nMAX = 3;
            int step = 1;
            double tc = 0;
            QuoteType sigType = QuoteType.AdjClose;
            bool calcMonthly = true;
            bool calcYearly = true;

            BackTestManager btManager = new BackTestManager("^OMX", Loader.Test, startDate, endDate, tc, sigType, calcYearly, calcMonthly);
            SortedList<int, BackTestManager.PerfSummary> summary = btManager.backTestEMAStrategy(nMIN, nMAX, step);
            // test summary size
            Assert.AreEqual( (nMAX-nMIN)+1, summary.Count, "summary.Count");
            double precision = 0.00001;
            
            // Test total PerfSummary
            Assert.AreEqual(-332.400, summary[2].Total.ProfitLoss, precision, "Total PL for nEMA=2");
            Assert.AreEqual(-395.910, summary[2].Total.MaxDrawDown, precision, "Total MaxDrawDown for nEMA=2");
            Assert.AreEqual(-0.839584754, summary[2].Total.Calmar, precision, "Total Calmar Ratio for nEMA=2");

            Assert.AreEqual(-217.62000, summary[3].Total.ProfitLoss, precision, "Total PL for nEMA=3");
            Assert.AreEqual(-280.17000, summary[3].Total.MaxDrawDown, precision, "Total MaxDrawDown for nEMA=3");
            Assert.AreEqual(-0.77674, summary[3].Total.Calmar, precision, "Total Calmar Ratio for nEMA=3");

            // Test Yearly Summary
            Assert.AreEqual(2, summary[nMIN].Yearly.Count, "Number of tested years");
            Assert.AreEqual(2009, summary[nMIN].Yearly[0].EndDate.Year, "Yearly: the first back-tested year");
            Assert.AreEqual(2010, summary[nMIN].Yearly[1].EndDate.Year, "Yearly: the second back-tested year");
            // nEMA=2, 2009
            Assert.AreEqual(-22.20000, summary[nMIN].Yearly[0].ProfitLoss, precision, "2009 PL for nEMA=2");
            Assert.AreEqual(-51.97000, summary[nMIN].Yearly[0].MaxDrawDown, precision, "2009 MaxDrawDown for nEMA=2");
            Assert.AreEqual(-0.42717, summary[nMIN].Yearly[0].Calmar, precision, "2009 Calmar ratio for nEMA=2");
            // nEMA=3, 2010
            Assert.AreEqual(-195.62000, summary[nMAX].Yearly[1].ProfitLoss, precision, "2010 PL for nEMA=3");
            Assert.AreEqual(-270.56000, summary[nMAX].Yearly[1].MaxDrawDown, precision, "2010 MaxDrawDown for nEMA=3");
            Assert.AreEqual(-0.72302, summary[nMAX].Yearly[1].Calmar, precision, "2010 Calmar for nEMA=3");

            // Test Monthly summary
            Assert.AreEqual(6, summary[nMIN].Monthly.Count, "Number of tested months");
            PerfStatistics dec2009Perf = summary[nMIN].Monthly[0];
            Assert.AreEqual(-22.20000, dec2009Perf.ProfitLoss, precision, "Dec2009 PL for nEMA=2");
            Assert.AreEqual(-51.97000, dec2009Perf.MaxDrawDown, precision, "Dec2009 MaxDrawDown for nEMA=2");
            Assert.AreEqual(-0.42717, dec2009Perf.Calmar, precision, "Dec2009 Calmar for nEMA=2");

            PerfStatistics jan2010Perf = summary[nMAX].Monthly[1];
            Assert.AreEqual(-52.77000, jan2010Perf.ProfitLoss, precision, "Jan2010 PL for nEMA=3");
            Assert.AreEqual(-79.08000, jan2010Perf.MaxDrawDown, precision, "Jan2010 MaxDD for nEMA=3");
            Assert.AreEqual(-0.66730, jan2010Perf.Calmar, precision, "Jan2010 Calmar for nEMA=3");
        }

        [Test]
        [Category("Calculation")]
        public void BackTestManagerEMAStrategyAllQuoteTypes()
        {
            DateTime startDate = new DateTime(2010, 4, 30);
            DateTime endDate = new DateTime(2010, 5, 31);
            int nMIN = 4;
            int nMAX = 4;
            int step = 1;
            double tc = 0;
            double tolerance = 0.000000001;
            bool calcMonthly = false;
            bool calcYearly = true;

            BackTestManager btManager = new BackTestManager("^OMX", Loader.Test, startDate, endDate, tc, QuoteType.AdjClose, calcYearly, calcMonthly);
            SortedList<int, BackTestManager.PerfSummary> summary = btManager.backTestEMAStrategy(nMIN, nMAX, step);
            Assert.AreEqual(-109.77, summary[nMIN].Total.ProfitLoss, tolerance, "AdjClose: TotPL");
            Assert.AreEqual(0, summary[nMIN].Monthly.Count, "0: No monthly figures should be produced");
            Assert.AreEqual(1, summary[nMIN].Yearly.Count, "0: Single year was produced");

            calcMonthly = true;
            calcYearly = false;
            btManager = new BackTestManager("^OMX", Loader.Test, startDate, endDate, tc, QuoteType.Open, calcYearly, calcMonthly);
            summary = btManager.backTestEMAStrategy(nMIN, nMAX, step);
            Assert.AreEqual(-109.77, summary[nMIN].Total.ProfitLoss, tolerance, "Open: TotPL");
            Assert.AreEqual(1, summary[nMIN].Monthly.Count, "1: Single month has been produced");
            Assert.AreEqual(0, summary[nMIN].Yearly.Count, "1: No year was produced");

            calcMonthly = false;
            calcYearly = false;
            btManager = new BackTestManager("^OMX", Loader.Test, startDate, endDate, tc, QuoteType.High, calcYearly, calcMonthly);
            summary = btManager.backTestEMAStrategy(nMIN, nMAX, step);
            Assert.AreEqual(1.03, summary[nMIN].Total.ProfitLoss, tolerance, "High: TotPL");
            Assert.AreEqual(0, summary[nMIN].Monthly.Count, "2: No month was produced");
            Assert.AreEqual(0, summary[nMIN].Yearly.Count, "2: No year was produced");

            btManager = new BackTestManager("^OMX", Loader.Test, startDate, endDate, tc, QuoteType.Low, calcYearly, calcMonthly);
            summary = btManager.backTestEMAStrategy(nMIN, nMAX, step);
            Assert.AreEqual(-117.43000, summary[nMIN].Total.ProfitLoss, tolerance, "High: TotPL");

            btManager = new BackTestManager("^OMX", Loader.Test, startDate, endDate, tc, QuoteType.AvgHLC, calcYearly, calcMonthly);
            summary = btManager.backTestEMAStrategy(nMIN, nMAX, step);
            Assert.AreEqual(-126.53000, summary[nMIN].Total.ProfitLoss, tolerance, "AvgHLC: TotPL");

            btManager = new BackTestManager("^OMX", Loader.Test, startDate, endDate, tc, QuoteType.AvgHL, calcYearly, calcMonthly);
            summary = btManager.backTestEMAStrategy(nMIN, nMAX, step);
            Assert.AreEqual(-144.03000, summary[nMIN].Total.ProfitLoss, tolerance, "AvgHL: TotPL");
            Assert.AreEqual(-187.42, summary[nMIN].Total.MaxDrawDown, tolerance, "AvgHL: MaxDD");

            btManager = new BackTestManager("^OMX", Loader.Test, startDate, endDate, tc, QuoteType.AvgHLC, calcYearly, calcMonthly);
            List<BackTestManager.TwoEmaPerfSummary> s = btManager.backTestTwoEMAStrategy(4, 4, 1, 8, 8, 1, 1,1,1);
            Assert.AreEqual(-39.13, s[0].Summary.Total.ProfitLoss, tolerance, "AvgHL: TotPL");
            Assert.AreEqual(-114.32, s[0].Summary.Total.MaxDrawDown, tolerance, "AvgHL: MaxDD");
        }

        [Test]
        [Category("Calculation")]
        public void BackTestManagerEMAStrategyWithTC()
        {
            DateTime startDate = new DateTime(2009, 11, 30);
            DateTime endDate = new DateTime(2010, 5, 31);
            int nMIN = 2;
            int nMAX = 3;
            int step = 1;
            double transactionCost = 0.01;
            QuoteType sigType = QuoteType.AdjClose;
            bool showYearly = true;
            bool showMonthly = true;

            BackTestManager btManager = new BackTestManager("^OMX", Loader.Test, startDate, endDate, transactionCost, sigType, showYearly, showMonthly);
            SortedList<int, BackTestManager.PerfSummary> summary = btManager.backTestEMAStrategy(nMIN, nMAX, step);
            // test summary size
            Assert.AreEqual((nMAX - nMIN) + 1, summary.Count, "summary.Count");
            double precision = 0.00001;

            // Test total PerfSummary
            Assert.AreEqual(-332.400 - 1508.3996, summary[2].Total.ProfitLoss, precision, "Total PL for nEMA=2 and TC");
            Assert.AreEqual(-1891.33959, summary[2].Total.MaxDrawDown, precision, "Total MaxDrawDown for nEMA=2 and TC");

            // Test Yearly Summary
            Assert.AreEqual(2, summary[nMIN].Yearly.Count, "Number of tested years, TC");
            Assert.AreEqual(2009, summary[nMIN].Yearly[0].EndDate.Year, "Yearly: the first back-tested year, TC");
            Assert.AreEqual(2010, summary[nMIN].Yearly[1].EndDate.Year, "Yearly: the second back-tested year, TC");
            // nEMA=2, 2009
            Assert.AreEqual(-22.20000 - 255.0960, summary[nMIN].Yearly[0].ProfitLoss, precision, "2009 PL for nEMA=2 and TC");
            Assert.AreEqual(-278.9560, summary[nMIN].Yearly[0].MaxDrawDown, precision, "2009 MaxDrawDown for nEMA=2 and TC");

            // Test Monthly summary
            Assert.AreEqual(6, summary[nMIN].Monthly.Count, "Number of tested months");
            PerfStatistics dec2009Perf = summary[nMIN].Monthly[0];
            Assert.AreEqual(-277.2960, dec2009Perf.ProfitLoss, precision, "Dec2009 PL for nEMA=2 and TC");
            Assert.AreEqual(-278.9560, dec2009Perf.MaxDrawDown, precision, "Dec2009 MaxDrawDown for nEMA=2 and TC");

            PerfStatistics jan2010Perf = summary[nMIN].Monthly[1];
            Assert.AreEqual(-444.1106, jan2010Perf.ProfitLoss, precision, "Jan2010 PL for nEMA=2 and TC");
            Assert.AreEqual(-456.3706, jan2010Perf.MaxDrawDown, precision, "Jan2010 MaxDrawDown for nEMA=2 and TC");
      }

        [Test]
        [Category("Calculation")]
        public void BackTestDTBuilderEMA()
        {
            DateTime startDate = new DateTime(2009, 11, 30);
            DateTime endDate = new DateTime(2010, 5, 31);
            int nMIN = 2;
            int nMAX = 3;
            int step = 1;
            double transactionCost = 0.01;
            QuoteType sigType = QuoteType.AdjClose;
            bool showYearly = true;
            bool showMonthly = true;
            double precision = 0.000000001;

            BackTestManager btManager = new BackTestManager("^OMX", Loader.Test, startDate, endDate, transactionCost, sigType, showYearly, showMonthly);
            SortedList<int, BackTestManager.PerfSummary> summary = btManager.backTestEMAStrategy(nMIN, nMAX, step);
            Assert.AreEqual(-1840.7996, summary[2].Total.ProfitLoss, precision, "Total PL for nEMA=2 and TC");

            BackTestDataTableBuilder dtBuilder = new BackTestDataTableBuilder();
            DataTable dTable = dtBuilder.createEMABackTest(summary, showYearly, showMonthly);
            Assert.AreEqual(-1840.7996, (double)dTable.Rows[0][1], precision, "dTable: Total PL for nEMA=2 and TC");

            string tmpFileName = "tmpBTDTBuilderEMA.csv";
            string referenceCacheFile = "..\\..\\Tests\\BTDTBuilderEMA.csv";
            Utilities.saveDataTableToCSV(tmpFileName, dTable);
            FileAssert.AreEqual(referenceCacheFile, tmpFileName, "0: comparing " + tmpFileName + " with " + referenceCacheFile);
            File.Delete(tmpFileName);
        }

        [Test]
        [Category("Calculation")]
        public void btEMAStrategyBug()
        {
            DateTime startDate = new DateTime(2010, 05, 29);
            DateTime endDate = new DateTime(2010, 5, 31);
            int nMIN = 2;
            int nMAX = 2;
            int step = 1;
            double transactionCost = 0.01;
            QuoteType sigType = QuoteType.AdjClose;
            bool showYearly = false;
            bool showMonthly = false;
            double precision = 0.000000001;

            BackTestManager btManager = new BackTestManager("^OMX", Loader.Test, startDate, endDate, transactionCost, sigType, showYearly, showMonthly);
            SortedList<int, BackTestManager.PerfSummary> summary = btManager.backTestEMAStrategy(nMIN, nMAX, step);
            Assert.AreEqual(24.68, summary[2].Total.ProfitLoss, precision, "Total PL for nEMA=2 and TC");
        }

        [Test]
        [Category("Calculation")]
        public void BackTestDTBuilderTwoEMA()
        {
            DateTime startDate = new DateTime(2009, 11, 30);
            DateTime endDate = new DateTime(2010, 5, 31);
            int nShortMIN = 2;
            int nShortMAX = 3;
            int shortStep = 1;
            int nLongMIN = 3;
            int nLongMAX = 4;
            int longStep = 1;
            double precision = 0.00001;
            double transCost = 0;
            double volMIN = 1;
            double volMAX = 1;
            double volSTEP = 1;
            bool calcMonthlyPerf = true;
            bool calcYearlyPerf = true;
            QuoteType sigType = QuoteType.AdjClose;

            BackTestManager btManager = new BackTestManager("^OMX", Loader.Test, startDate, endDate, transCost, sigType, calcYearlyPerf, calcMonthlyPerf);
            List<BackTestManager.TwoEmaPerfSummary> result = btManager.backTestTwoEMAStrategy(nShortMIN, nShortMAX, shortStep, nLongMIN, nLongMAX, longStep, volMIN, volMAX, volSTEP);

            PerfStatistics tot = result[0].Summary.Total;
            Assert.AreEqual(-230.600, tot.ProfitLoss, precision, "total PL, nShort=2, nLong=3");
            Assert.AreEqual(-293.150, tot.MaxDrawDown, precision, "total MaxDD, nShort=2, nLong=3");
            Assert.AreEqual(-0.786628006, tot.Calmar, precision, "total Calmar, nShort=2, nLong=3");

            BackTestDataTableBuilder dtBuilder = new BackTestDataTableBuilder();
            DataTable dTable = dtBuilder.createTwoEMADataTable(result, calcYearlyPerf, calcMonthlyPerf);
            Assert.AreEqual(-230.600, (double)dTable.Rows[0][3], precision, "dTable: totalPL");
            Assert.AreEqual(-293.150, (double)dTable.Rows[0][4], precision, "dTable: maxDD");
            Assert.AreEqual(-0.786628006, (double)dTable.Rows[0][5], precision, "dTable: Calmar");

            string tmpFileName = "tmpBTDTBuilderTwoEma.csv";
            string referenceCacheFile = "..\\..\\Tests\\BTDTBuilderTwoEma.csv";
            Utilities.saveDataTableToCSV(tmpFileName, dTable);
            FileAssert.AreEqual(referenceCacheFile, tmpFileName, "0: comparing " + tmpFileName + " with " + referenceCacheFile);
            File.Delete(tmpFileName);
        }

        [Test]
        [Category("Calculation")]
        public void BackTestManagerTwoEMAStrategy()
        {
            DateTime startDate = new DateTime(2009, 11, 30);
            DateTime endDate = new DateTime(2010, 5, 31);
            int nShortMIN = 2;
            int nShortMAX = 3;
            int shortStep = 1;
            int nLongMIN = 3;
            int nLongMAX = 5;
            int longStep = 1;
            double precision = 0.00001;
            double transCost = 0;
            double volMIN = 1;
            double volMAX = 1;
            double volSTEP = 1;
            bool calcMonthlyPerf = true;
            bool calcYearlyPerf = true;
            QuoteType sigType = QuoteType.AdjClose;

            BackTestManager btManager = new BackTestManager("^OMX", Loader.Test, startDate, endDate, transCost, sigType, calcYearlyPerf, calcMonthlyPerf);
            List<BackTestManager.TwoEmaPerfSummary> result = btManager.backTestTwoEMAStrategy(nShortMIN, nShortMAX, shortStep, nLongMIN, nLongMAX, longStep, volMIN, volMAX, volSTEP);

            // test number of elements in the list
            Assert.AreEqual(5, result.Count, "result.Count");

            // ==> test the nShort=2, nLong=3 <==
            Assert.AreEqual(2, result[0].NEmaShort, "nShort[0]");
            Assert.AreEqual(3, result[0].NEmaLong, "nLong[0]");
            //  Total
            PerfStatistics tot = result[0].Summary.Total;
            Assert.AreEqual(-230.600, tot.ProfitLoss, precision, "total PL, nShort=2, nLong=3");
            Assert.AreEqual(-293.150, tot.MaxDrawDown, precision, "total MaxDD, nShort=2, nLong=3");
            Assert.AreEqual(-0.786628006, tot.Calmar, precision, "total Calmar, nShort=2, nLong=3");
            //  Yearly 2009
            PerfStatistics stat2009 = result[0].Summary.Yearly[0];
            Assert.AreEqual(-24.48, stat2009.ProfitLoss, precision, "yearly 2009 PL: nShort=2, nLong=3");
            Assert.AreEqual(-67.85, stat2009.MaxDrawDown, precision, "yearly 2009 MaxDD: nShort=2, nLong=3");
            Assert.AreEqual(-0.3608, stat2009.Calmar, precision, "yearly 2009 Calmar: nShort=2, nLong=3");
            //  Yearly 2010
            PerfStatistics stat2010 = result[0].Summary.Yearly[1];
            Assert.AreEqual(-206.12, stat2010.ProfitLoss, precision, "yearly 2010 PL: nShort=2, nLong=3");
            Assert.AreEqual(-286.54, stat2010.MaxDrawDown, precision, "yearly 2010 MaxDD: nShort=2, nLong=3");
            Assert.AreEqual(-0.71934, stat2010.Calmar, precision, "yearly 2010 Calmar: nShort=2, nLong=3");
            //  Monthly Jan2010
            PerfStatistics statJan2010 = result[0].Summary.Monthly[1];
            Assert.AreEqual(-42.2300, statJan2010.ProfitLoss, precision, "monthly jan 2010 PL: nShort=2, nLong=3");
            Assert.AreEqual(-74.0200, statJan2010.MaxDrawDown, precision, "monthly jan 2010 MaxDD: nShort=2, nLong=3");
            Assert.AreEqual(-0.57052, statJan2010.Calmar, precision, "monthly jan 2010 Calmar: nShort=2, nLong=3");

            // ==> test nShort=2, nLong=5 <==
            Assert.AreEqual(2, result[3].NEmaShort, "nShort[1]");
            Assert.AreEqual(5, result[3].NEmaLong, "nLong[1]");
            //  Total
            tot = result[3].Summary.Total;
            Assert.AreEqual(-308.540, tot.ProfitLoss, precision, "total PL, nShort=2, nLong=3");
            Assert.AreEqual(-343.820, tot.MaxDrawDown, precision, "total MaxDD, nShort=2, nLong=3");
            Assert.AreEqual(-0.897388168, tot.Calmar, precision, "total Calmar, nShort=2, nLong=3");
            //  Yearly 2009
            stat2009 = result[3].Summary.Yearly[0];
            Assert.AreEqual(-12.12, stat2009.ProfitLoss, precision, "yearly 2009 PL: nShort=2, nLong=5");
            Assert.AreEqual(-52.01, stat2009.MaxDrawDown, precision, "yearly 2009 MaxDD: nShort=2, nLong=5");
            Assert.AreEqual(-0.23303, stat2009.Calmar, precision, "yearly 2009 Calmar: nShort=2, nLong=5");
            //  Yearly 2010
            stat2010 = result[3].Summary.Yearly[1];
            Assert.AreEqual(-296.42, stat2010.ProfitLoss, precision, "yearly 2010 PL: nShort=2, nLong=5");
            Assert.AreEqual(-337.85, stat2010.MaxDrawDown, precision, "yearly 2010 MaxDD: nShort=2, nLong=5");
            Assert.AreEqual(-0.87737, stat2010.Calmar, precision, "yearly 2010 Calmar: nShort=2, nLong=5");
            // Monthly Jan 2010
            statJan2010 = result[3].Summary.Monthly[1];
            Assert.AreEqual(-100.4100, statJan2010.ProfitLoss, precision, "monthly jan 2010 PL: nShort=2, nLong=5");
            Assert.AreEqual(-125.9600, statJan2010.MaxDrawDown, precision, "monthly jan 2010 MaxDD: nShort=2, nLong=5");
            Assert.AreEqual(-0.79716, statJan2010.Calmar, precision, "monthly jan 2010 Calmar: nShort=2, nLong=5");

            // ==> Other scenarios <==
            Assert.AreEqual(2, result[1].NEmaShort, "nShort[1]");
            Assert.AreEqual(4, result[1].NEmaLong, "nLong[1]");
            Assert.AreEqual(3, result[2].NEmaShort, "nShort[1]");
            Assert.AreEqual(4, result[2].NEmaLong, "nLong[1]");
            Assert.AreEqual(3, result[4].NEmaShort, "nShort[1]");
            Assert.AreEqual(5, result[4].NEmaLong, "nLong[1]");

        }

        /// <summary>Generate Russel3000 historical prices</summary>
        /// <returns>Russel3000 prices from 2009-01-01 to 2010-06-28</returns>
        private SortedList<DateTime, double> getRussel3000Prices()
        {
            SortedList<DateTime, double> prices = new SortedList<DateTime, double>(374);
            prices.Add(new DateTime(2009, 1, 2), 536.26);
            prices.Add(new DateTime(2009, 1, 5), 534.43);
            prices.Add(new DateTime(2009, 1, 6), 539.78);
            prices.Add(new DateTime(2009, 1, 7), 523.37);
            prices.Add(new DateTime(2009, 1, 8), 525.88);
            prices.Add(new DateTime(2009, 1, 9), 513.9);
            prices.Add(new DateTime(2009, 1, 12), 501.61);
            prices.Add(new DateTime(2009, 1, 13), 503.23);
            prices.Add(new DateTime(2009, 1, 14), 485.68);
            prices.Add(new DateTime(2009, 1, 15), 487.71);
            prices.Add(new DateTime(2009, 1, 16), 491.8);
            prices.Add(new DateTime(2009, 1, 20), 464.73);
            prices.Add(new DateTime(2009, 1, 21), 485.21);
            prices.Add(new DateTime(2009, 1, 22), 476.83);
            prices.Add(new DateTime(2009, 1, 23), 479.61);
            prices.Add(new DateTime(2009, 1, 26), 482.41);
            prices.Add(new DateTime(2009, 1, 27), 487.72);
            prices.Add(new DateTime(2009, 1, 28), 504.42);
            prices.Add(new DateTime(2009, 1, 29), 487.33);
            prices.Add(new DateTime(2009, 1, 30), 476.26);
            prices.Add(new DateTime(2009, 2, 2), 476.64);
            prices.Add(new DateTime(2009, 2, 3), 483.57);
            prices.Add(new DateTime(2009, 2, 4), 480.28);
            prices.Add(new DateTime(2009, 2, 5), 488.16);
            prices.Add(new DateTime(2009, 2, 6), 501.98);
            prices.Add(new DateTime(2009, 2, 9), 502.34);
            prices.Add(new DateTime(2009, 2, 10), 478.16);
            prices.Add(new DateTime(2009, 2, 11), 481.54);
            prices.Add(new DateTime(2009, 2, 12), 482.8);
            prices.Add(new DateTime(2009, 2, 13), 478.33);
            prices.Add(new DateTime(2009, 2, 17), 456.65);
            prices.Add(new DateTime(2009, 2, 18), 455.41);
            prices.Add(new DateTime(2009, 2, 19), 449.7);
            prices.Add(new DateTime(2009, 2, 20), 444.73);
            prices.Add(new DateTime(2009, 2, 23), 428.91);
            prices.Add(new DateTime(2009, 2, 24), 446.45);
            prices.Add(new DateTime(2009, 2, 25), 441.13);
            prices.Add(new DateTime(2009, 2, 26), 433.96);
            prices.Add(new DateTime(2009, 2, 27), 424.88);
            prices.Add(new DateTime(2009, 3, 2), 404.26);
            prices.Add(new DateTime(2009, 3, 3), 401.44);
            prices.Add(new DateTime(2009, 3, 4), 411.36);
            prices.Add(new DateTime(2009, 3, 5), 393.34);
            prices.Add(new DateTime(2009, 3, 6), 393.85);
            prices.Add(new DateTime(2009, 3, 9), 389.61);
            prices.Add(new DateTime(2009, 3, 10), 414.69);
            prices.Add(new DateTime(2009, 3, 11), 415.62);
            prices.Add(new DateTime(2009, 3, 12), 433.3);
            prices.Add(new DateTime(2009, 3, 13), 436.52);
            prices.Add(new DateTime(2009, 3, 16), 434.08);
            prices.Add(new DateTime(2009, 3, 17), 448.43);
            prices.Add(new DateTime(2009, 3, 18), 458.44);
            prices.Add(new DateTime(2009, 3, 19), 453.04);
            prices.Add(new DateTime(2009, 3, 20), 443.43);
            prices.Add(new DateTime(2009, 3, 23), 475.05);
            prices.Add(new DateTime(2009, 3, 24), 464.68);
            prices.Add(new DateTime(2009, 3, 25), 469.72);
            prices.Add(new DateTime(2009, 3, 26), 482.03);
            prices.Add(new DateTime(2009, 3, 27), 471.31);
            prices.Add(new DateTime(2009, 3, 30), 454.99);
            prices.Add(new DateTime(2009, 3, 31), 461.14);
            prices.Add(new DateTime(2009, 4, 1), 468.65);
            prices.Add(new DateTime(2009, 4, 2), 483.36);
            prices.Add(new DateTime(2009, 4, 3), 488.65);
            prices.Add(new DateTime(2009, 4, 6), 484.07);
            prices.Add(new DateTime(2009, 4, 7), 471.71);
            prices.Add(new DateTime(2009, 4, 8), 477.91);
            prices.Add(new DateTime(2009, 4, 9), 497.33);
            prices.Add(new DateTime(2009, 4, 13), 498.38);
            prices.Add(new DateTime(2009, 4, 14), 487.84);
            prices.Add(new DateTime(2009, 4, 15), 494.06);
            prices.Add(new DateTime(2009, 4, 16), 502.7);
            prices.Add(new DateTime(2009, 4, 17), 505.69);
            prices.Add(new DateTime(2009, 4, 20), 482.99);
            prices.Add(new DateTime(2009, 4, 21), 494.32);
            prices.Add(new DateTime(2009, 4, 22), 491.29);
            prices.Add(new DateTime(2009, 4, 23), 494.9);
            prices.Add(new DateTime(2009, 4, 24), 504.04);
            prices.Add(new DateTime(2009, 4, 27), 498.39);
            prices.Add(new DateTime(2009, 4, 28), 497.53);
            prices.Add(new DateTime(2009, 4, 29), 509.39);
            prices.Add(new DateTime(2009, 4, 30), 508.91);
            prices.Add(new DateTime(2009, 5, 1), 511.27);
            prices.Add(new DateTime(2009, 5, 4), 529.33);
            prices.Add(new DateTime(2009, 5, 5), 527.1);
            prices.Add(new DateTime(2009, 5, 6), 535.17);
            prices.Add(new DateTime(2009, 5, 7), 527);
            prices.Add(new DateTime(2009, 5, 8), 540.64);
            prices.Add(new DateTime(2009, 5, 11), 529.26);
            prices.Add(new DateTime(2009, 5, 12), 527.76);
            prices.Add(new DateTime(2009, 5, 13), 512.02);
            prices.Add(new DateTime(2009, 5, 14), 517.89);
            prices.Add(new DateTime(2009, 5, 15), 512.16);
            prices.Add(new DateTime(2009, 5, 18), 528.55);
            prices.Add(new DateTime(2009, 5, 19), 527.9);
            prices.Add(new DateTime(2009, 5, 20), 525.26);
            prices.Add(new DateTime(2009, 5, 21), 516.35);
            prices.Add(new DateTime(2009, 5, 22), 515.37);
            prices.Add(new DateTime(2009, 5, 26), 530.01);
            prices.Add(new DateTime(2009, 5, 27), 520.05);
            prices.Add(new DateTime(2009, 5, 28), 527.31);
            prices.Add(new DateTime(2009, 5, 29), 534.75);
            prices.Add(new DateTime(2009, 6, 1), 549.68);
            prices.Add(new DateTime(2009, 6, 2), 551.14);
            prices.Add(new DateTime(2009, 6, 3), 543.41);
            prices.Add(new DateTime(2009, 6, 4), 550.01);
            prices.Add(new DateTime(2009, 6, 5), 548.73);
            prices.Add(new DateTime(2009, 6, 8), 547.38);
            prices.Add(new DateTime(2009, 6, 9), 549.91);
            prices.Add(new DateTime(2009, 6, 10), 547.94);
            prices.Add(new DateTime(2009, 6, 11), 551.18);
            prices.Add(new DateTime(2009, 6, 12), 551.57);
            prices.Add(new DateTime(2009, 6, 15), 538.16);
            prices.Add(new DateTime(2009, 6, 16), 530.95);
            prices.Add(new DateTime(2009, 6, 17), 530.42);
            prices.Add(new DateTime(2009, 6, 18), 534.47);
            prices.Add(new DateTime(2009, 6, 19), 536.38);
            prices.Add(new DateTime(2009, 6, 22), 519.38);
            prices.Add(new DateTime(2009, 6, 23), 520.04);
            prices.Add(new DateTime(2009, 6, 24), 523.98);
            prices.Add(new DateTime(2009, 6, 25), 535.56);
            prices.Add(new DateTime(2009, 6, 26), 535.56);
            prices.Add(new DateTime(2009, 6, 29), 539.73);
            prices.Add(new DateTime(2009, 6, 30), 535.62);
            prices.Add(new DateTime(2009, 7, 1), 538.65);
            prices.Add(new DateTime(2009, 7, 2), 522.57);
            prices.Add(new DateTime(2009, 7, 6), 522.95);
            prices.Add(new DateTime(2009, 7, 7), 512.51);
            prices.Add(new DateTime(2009, 7, 8), 511.18);
            prices.Add(new DateTime(2009, 7, 9), 513.05);
            prices.Add(new DateTime(2009, 7, 10), 511.36);
            prices.Add(new DateTime(2009, 7, 13), 523.87);
            prices.Add(new DateTime(2009, 7, 14), 526.93);
            prices.Add(new DateTime(2009, 7, 15), 542.91);
            prices.Add(new DateTime(2009, 7, 16), 548.08);
            prices.Add(new DateTime(2009, 7, 17), 547.61);
            prices.Add(new DateTime(2009, 7, 20), 554.38);
            prices.Add(new DateTime(2009, 7, 21), 556.07);
            prices.Add(new DateTime(2009, 7, 22), 556.23);
            prices.Add(new DateTime(2009, 7, 23), 569.71);
            prices.Add(new DateTime(2009, 7, 24), 571.82);
            prices.Add(new DateTime(2009, 7, 27), 573.58);
            prices.Add(new DateTime(2009, 7, 28), 572.23);
            prices.Add(new DateTime(2009, 7, 29), 569.23);
            prices.Add(new DateTime(2009, 7, 30), 576.31);
            prices.Add(new DateTime(2009, 7, 31), 576.56);
            prices.Add(new DateTime(2009, 8, 3), 585.93);
            prices.Add(new DateTime(2009, 8, 4), 588.14);
            prices.Add(new DateTime(2009, 8, 5), 586.31);
            prices.Add(new DateTime(2009, 8, 6), 582.42);
            prices.Add(new DateTime(2009, 8, 7), 591.21);
            prices.Add(new DateTime(2009, 8, 10), 589.27);
            prices.Add(new DateTime(2009, 8, 11), 581.6);
            prices.Add(new DateTime(2009, 8, 12), 588.54);
            prices.Add(new DateTime(2009, 8, 13), 592.68);
            prices.Add(new DateTime(2009, 8, 14), 586.87);
            prices.Add(new DateTime(2009, 8, 17), 572.13);
            prices.Add(new DateTime(2009, 8, 18), 578.35);
            prices.Add(new DateTime(2009, 8, 19), 582.4);
            prices.Add(new DateTime(2009, 8, 20), 588.76);
            prices.Add(new DateTime(2009, 8, 21), 599.79);
            prices.Add(new DateTime(2009, 8, 24), 599.16);
            prices.Add(new DateTime(2009, 8, 25), 600.75);
            prices.Add(new DateTime(2009, 8, 26), 600.85);
            prices.Add(new DateTime(2009, 8, 27), 602.42);
            prices.Add(new DateTime(2009, 8, 28), 601.3);
            prices.Add(new DateTime(2009, 8, 31), 595.86);
            prices.Add(new DateTime(2009, 9, 1), 582.63);
            prices.Add(new DateTime(2009, 9, 2), 580.65);
            prices.Add(new DateTime(2009, 9, 3), 586.08);
            prices.Add(new DateTime(2009, 9, 4), 593.87);
            prices.Add(new DateTime(2009, 9, 8), 599.59);
            prices.Add(new DateTime(2009, 9, 9), 604.99);
            prices.Add(new DateTime(2009, 9, 10), 611.61);
            prices.Add(new DateTime(2009, 9, 11), 610.92);
            prices.Add(new DateTime(2009, 9, 14), 615.23);
            prices.Add(new DateTime(2009, 9, 15), 617.93);
            prices.Add(new DateTime(2009, 9, 16), 627.8);
            prices.Add(new DateTime(2009, 9, 17), 625.64);
            prices.Add(new DateTime(2009, 9, 18), 627.17);
            prices.Add(new DateTime(2009, 9, 21), 625.2);
            prices.Add(new DateTime(2009, 9, 22), 629.49);
            prices.Add(new DateTime(2009, 9, 23), 622.74);
            prices.Add(new DateTime(2009, 9, 24), 615.82);
            prices.Add(new DateTime(2009, 9, 25), 612.2);
            prices.Add(new DateTime(2009, 9, 28), 623.53);
            prices.Add(new DateTime(2009, 9, 29), 622.33);
            prices.Add(new DateTime(2009, 9, 30), 619.87);
            prices.Add(new DateTime(2009, 10, 1), 603.16);
            prices.Add(new DateTime(2009, 10, 2), 600.06);
            prices.Add(new DateTime(2009, 10, 5), 609.56);
            prices.Add(new DateTime(2009, 10, 6), 618.12);
            prices.Add(new DateTime(2009, 10, 7), 619.63);
            prices.Add(new DateTime(2009, 10, 8), 624.81);
            prices.Add(new DateTime(2009, 10, 9), 628.66);
            prices.Add(new DateTime(2009, 10, 12), 631.07);
            prices.Add(new DateTime(2009, 10, 13), 629.19);
            prices.Add(new DateTime(2009, 10, 14), 640.38);
            prices.Add(new DateTime(2009, 10, 15), 642.68);
            prices.Add(new DateTime(2009, 10, 16), 637.18);
            prices.Add(new DateTime(2009, 10, 19), 643.32);
            prices.Add(new DateTime(2009, 10, 20), 638.71);
            prices.Add(new DateTime(2009, 10, 21), 632.71);
            prices.Add(new DateTime(2009, 10, 22), 639.55);
            prices.Add(new DateTime(2009, 10, 23), 631.22);
            prices.Add(new DateTime(2009, 10, 26), 623.69);
            prices.Add(new DateTime(2009, 10, 27), 620.73);
            prices.Add(new DateTime(2009, 10, 28), 606.95);
            prices.Add(new DateTime(2009, 10, 29), 620.79);
            prices.Add(new DateTime(2009, 10, 30), 603.26);
            prices.Add(new DateTime(2009, 11, 2), 606.69);
            prices.Add(new DateTime(2009, 11, 3), 609.41);
            prices.Add(new DateTime(2009, 11, 4), 609.16);
            prices.Add(new DateTime(2009, 11, 5), 621.74);
            prices.Add(new DateTime(2009, 11, 6), 622.92);
            prices.Add(new DateTime(2009, 11, 9), 636.79);
            prices.Add(new DateTime(2009, 11, 10), 636.34);
            prices.Add(new DateTime(2009, 11, 11), 639.87);
            prices.Add(new DateTime(2009, 11, 12), 632.43);
            prices.Add(new DateTime(2009, 11, 13), 636.47);
            prices.Add(new DateTime(2009, 11, 16), 646.5);
            prices.Add(new DateTime(2009, 11, 17), 646.96);
            prices.Add(new DateTime(2009, 11, 18), 646.21);
            prices.Add(new DateTime(2009, 11, 19), 636.7);
            prices.Add(new DateTime(2009, 11, 20), 634.57);
            prices.Add(new DateTime(2009, 11, 23), 643.05);
            prices.Add(new DateTime(2009, 11, 24), 642.47);
            prices.Add(new DateTime(2009, 11, 25), 645.35);
            prices.Add(new DateTime(2009, 11, 27), 633.72);
            prices.Add(new DateTime(2009, 11, 30), 636.04);
            prices.Add(new DateTime(2009, 12, 1), 644.23);
            prices.Add(new DateTime(2009, 12, 2), 645.38);
            prices.Add(new DateTime(2009, 12, 3), 639.75);
            prices.Add(new DateTime(2009, 12, 4), 644.45);
            prices.Add(new DateTime(2009, 12, 7), 643.17);
            prices.Add(new DateTime(2009, 12, 8), 636.74);
            prices.Add(new DateTime(2009, 12, 9), 638.83);
            prices.Add(new DateTime(2009, 12, 10), 642.11);
            prices.Add(new DateTime(2009, 12, 11), 644.84);
            prices.Add(new DateTime(2009, 12, 14), 650.26);
            prices.Add(new DateTime(2009, 12, 15), 646.99);
            prices.Add(new DateTime(2009, 12, 16), 648.4);
            prices.Add(new DateTime(2009, 12, 17), 640.88);
            prices.Add(new DateTime(2009, 12, 18), 644.91);
            prices.Add(new DateTime(2009, 12, 21), 651.83);
            prices.Add(new DateTime(2009, 12, 22), 654.73);
            prices.Add(new DateTime(2009, 12, 23), 656.99);
            prices.Add(new DateTime(2009, 12, 24), 660.44);
            prices.Add(new DateTime(2009, 12, 28), 660.91);
            prices.Add(new DateTime(2009, 12, 29), 659.91);
            prices.Add(new DateTime(2009, 12, 30), 659.96);
            prices.Add(new DateTime(2009, 12, 31), 653.13);
            prices.Add(new DateTime(2010, 1, 4), 664.05);
            prices.Add(new DateTime(2010, 1, 5), 665.97);
            prices.Add(new DateTime(2010, 1, 6), 666.55);
            prices.Add(new DateTime(2010, 1, 7), 669.34);
            prices.Add(new DateTime(2010, 1, 8), 671.49);
            prices.Add(new DateTime(2010, 1, 11), 672.38);
            prices.Add(new DateTime(2010, 1, 12), 665.54);
            prices.Add(new DateTime(2010, 1, 13), 671.54);
            prices.Add(new DateTime(2010, 1, 14), 673.15);
            prices.Add(new DateTime(2010, 1, 15), 665.67);
            prices.Add(new DateTime(2010, 1, 19), 674.19);
            prices.Add(new DateTime(2010, 1, 20), 667.02);
            prices.Add(new DateTime(2010, 1, 21), 654.91);
            prices.Add(new DateTime(2010, 1, 22), 640.75);
            prices.Add(new DateTime(2010, 1, 25), 643.5);
            prices.Add(new DateTime(2010, 1, 26), 640.58);
            prices.Add(new DateTime(2010, 1, 27), 643.65);
            prices.Add(new DateTime(2010, 1, 28), 635.6);
            prices.Add(new DateTime(2010, 1, 29), 628.99);
            prices.Add(new DateTime(2010, 2, 1), 638.14);
            prices.Add(new DateTime(2010, 2, 2), 646.25);
            prices.Add(new DateTime(2010, 2, 3), 642.61);
            prices.Add(new DateTime(2010, 2, 4), 622.22);
            prices.Add(new DateTime(2010, 2, 5), 624.04);
            prices.Add(new DateTime(2010, 2, 8), 618.63);
            prices.Add(new DateTime(2010, 2, 9), 626.8);
            prices.Add(new DateTime(2010, 2, 10), 625.6);
            prices.Add(new DateTime(2010, 2, 11), 632.41);
            prices.Add(new DateTime(2010, 2, 12), 631.87);
            prices.Add(new DateTime(2010, 2, 16), 643.28);
            prices.Add(new DateTime(2010, 2, 17), 646.22);
            prices.Add(new DateTime(2010, 2, 18), 650.43);
            prices.Add(new DateTime(2010, 2, 19), 651.9);
            prices.Add(new DateTime(2010, 2, 22), 651.26);
            prices.Add(new DateTime(2010, 2, 23), 643.13);
            prices.Add(new DateTime(2010, 2, 24), 649.21);
            prices.Add(new DateTime(2010, 2, 25), 648.22);
            prices.Add(new DateTime(2010, 2, 26), 648.9);
            prices.Add(new DateTime(2010, 3, 1), 656.5);
            prices.Add(new DateTime(2010, 3, 2), 658.79);
            prices.Add(new DateTime(2010, 3, 3), 658.96);
            prices.Add(new DateTime(2010, 3, 4), 661.3);
            prices.Add(new DateTime(2010, 3, 5), 670.98);
            prices.Add(new DateTime(2010, 3, 8), 671.12);
            prices.Add(new DateTime(2010, 3, 9), 672.39);
            prices.Add(new DateTime(2010, 3, 10), 675.9);
            prices.Add(new DateTime(2010, 3, 11), 678.48);
            prices.Add(new DateTime(2010, 3, 12), 678.5);
            prices.Add(new DateTime(2010, 3, 15), 678.32);
            prices.Add(new DateTime(2010, 3, 16), 683.83);
            prices.Add(new DateTime(2010, 3, 17), 687.95);
            prices.Add(new DateTime(2010, 3, 18), 687.21);
            prices.Add(new DateTime(2010, 3, 19), 683.05);
            prices.Add(new DateTime(2010, 3, 22), 687.38);
            prices.Add(new DateTime(2010, 3, 23), 692.65);
            prices.Add(new DateTime(2010, 3, 24), 688.62);
            prices.Add(new DateTime(2010, 3, 25), 686.66);
            prices.Add(new DateTime(2010, 3, 26), 687.07);
            prices.Add(new DateTime(2010, 3, 29), 691.13);
            prices.Add(new DateTime(2010, 3, 30), 691.29);
            prices.Add(new DateTime(2010, 3, 31), 688.74);
            prices.Add(new DateTime(2010, 4, 1), 694.03);
            prices.Add(new DateTime(2010, 4, 5), 700.79);
            prices.Add(new DateTime(2010, 4, 6), 702.35);
            prices.Add(new DateTime(2010, 4, 7), 698.39);
            prices.Add(new DateTime(2010, 4, 8), 700.33);
            prices.Add(new DateTime(2010, 4, 9), 705.09);
            prices.Add(new DateTime(2010, 4, 12), 706.4);
            prices.Add(new DateTime(2010, 4, 13), 707.09);
            prices.Add(new DateTime(2010, 4, 14), 715.78);
            prices.Add(new DateTime(2010, 4, 15), 716.36);
            prices.Add(new DateTime(2010, 4, 16), 705.24);
            prices.Add(new DateTime(2010, 4, 19), 707.19);
            prices.Add(new DateTime(2010, 4, 20), 713.62);
            prices.Add(new DateTime(2010, 4, 21), 713.55);
            prices.Add(new DateTime(2010, 4, 22), 716.23);
            prices.Add(new DateTime(2010, 4, 23), 721.81);
            prices.Add(new DateTime(2010, 4, 26), 718.74);
            prices.Add(new DateTime(2010, 4, 27), 701.84);
            prices.Add(new DateTime(2010, 4, 28), 705.8);
            prices.Add(new DateTime(2010, 4, 29), 715.64);
            prices.Add(new DateTime(2010, 4, 30), 702.94);
            prices.Add(new DateTime(2010, 5, 3), 712.72);
            prices.Add(new DateTime(2010, 5, 4), 694.88);
            prices.Add(new DateTime(2010, 5, 5), 689.32);
            prices.Add(new DateTime(2010, 5, 6), 666.59);
            prices.Add(new DateTime(2010, 5, 7), 655.02);
            prices.Add(new DateTime(2010, 5, 10), 684.74);
            prices.Add(new DateTime(2010, 5, 11), 683.35);
            prices.Add(new DateTime(2010, 5, 12), 694.33);
            prices.Add(new DateTime(2010, 5, 13), 686.33);
            prices.Add(new DateTime(2010, 5, 14), 672.89);
            prices.Add(new DateTime(2010, 5, 17), 673.66);
            prices.Add(new DateTime(2010, 5, 18), 663.75);
            prices.Add(new DateTime(2010, 5, 19), 659.56);
            prices.Add(new DateTime(2010, 5, 20), 632.99);
            prices.Add(new DateTime(2010, 5, 21), 642.64);
            prices.Add(new DateTime(2010, 5, 24), 634.65);
            prices.Add(new DateTime(2010, 5, 25), 634.72);
            prices.Add(new DateTime(2010, 5, 26), 632.24);
            prices.Add(new DateTime(2010, 5, 27), 653.93);
            prices.Add(new DateTime(2010, 5, 28), 646.04);
            prices.Add(new DateTime(2010, 6, 1), 633.52);
            prices.Add(new DateTime(2010, 6, 2), 650.34);
            prices.Add(new DateTime(2010, 6, 3), 653.66);
            prices.Add(new DateTime(2010, 6, 4), 629.97);
            prices.Add(new DateTime(2010, 6, 7), 620.38);
            prices.Add(new DateTime(2010, 6, 8), 626);
            prices.Add(new DateTime(2010, 6, 9), 623.13);
            prices.Add(new DateTime(2010, 6, 10), 641.95);
            prices.Add(new DateTime(2010, 6, 11), 645.69);
            prices.Add(new DateTime(2010, 6, 14), 645.21);
            prices.Add(new DateTime(2010, 6, 15), 660.51);
            prices.Add(new DateTime(2010, 6, 16), 659.68);
            prices.Add(new DateTime(2010, 6, 17), 660.05);
            prices.Add(new DateTime(2010, 6, 18), 660.71);
            prices.Add(new DateTime(2010, 6, 21), 657.61);
            prices.Add(new DateTime(2010, 6, 22), 646.32);
            prices.Add(new DateTime(2010, 6, 23), 644.53);
            prices.Add(new DateTime(2010, 6, 24), 633.54);
            prices.Add(new DateTime(2010, 6, 25), 636.23);
            prices.Add(new DateTime(2010, 6, 28), 634.56);
            return prices;
        }
    }
}
